package org.springmvc.dao;

import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springmvc.model.BaseEntity;
import org.springmvc.pagination.Page;
import org.springmvc.pagination.PageUtill;
import org.springmvc.pagination.Pageable;

/**
 * 基础DAO
 * 
 * @author 唐家林
 * @time 2014年9月5日
 * @param <E>
 *            实体
 */
public abstract class AbstractBaseDao<E extends BaseEntity> {

	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;
	/**
	 * 在同一线程获取Session
	 * @return 返回获取到的Session
	 */
	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	/**
	 * 获得SessionFactory
	 * @return 返回SessionFactory
	 */
	protected SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	/**
	 * 创建一个新的Session
	 * <p>
	 * PS:使用该方法获得Session之后必须手动关闭
	 * @return Session 返回创建的Session
	 */
	protected Session openSession() {
		return sessionFactory.openSession();
	}

	/**
	 * 实体类型
	 */
	private Class<E> entityClass;

	/**
	 * 获取实体类型
	 * @return Class<E>
	 */
	protected Class<E> getEntityClass() {
		return entityClass;
	}

	/**
	 * 构造方法
	 */
	@SuppressWarnings("unchecked")
	public AbstractBaseDao() {
		ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
		this.entityClass = (Class<E>) type.getActualTypeArguments()[0];
	}

	/**
	 * 获取总记录数
	 * @return 记录总数
	 */
	public Long countAll() {
		return countAll(entityClass);
	}

	/**
	 * 获取总记录数
	 * @param entityClass 实体类型
	 * @return 记录总数
	 */
	protected Long countAll(Class<E> entityClass) {
		String hql = "SELECT COUNT(_table.id) FROM " + entityClass.getName() + " AS _table";
		Object[] values = null;
		return count(QueryType.HQL, hql, values);
	}

	/**
	 * 获取总记录数
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param list 参数值集合
	 * @return 记录总数
	 */
	protected Long count(QueryType queryType, String ql, List<Object> list) {
		if (ql == null) {
			return 0L;
		}
		String target = ql.substring(0, ql.toUpperCase().indexOf("FROM"));
		ql = ql.replace(target, "SELECT COUNT(*) ");
		Query q = createQuery(queryType, ql);
		int size = 0;
		if (list != null && (size = list.size()) > 0) {
			for (int i = 0; i < size; i++) {
				q.setParameter(i, list.get(i));
			}
		}
		Object count = q.uniqueResult();
		return Long.valueOf(String.valueOf(count));
	}

	/**
	 * 获取总记录数
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @return 记录总数
	 */
	protected Long count(QueryType queryType, String ql, Map<String, Object> condition) {
		if (ql == null) {
			return 0L;
		}
		String target = ql.substring(0, ql.toUpperCase().indexOf("FROM"));
		ql = ql.replace(target, "SELECT COUNT(*) ");
		Query q = createQuery(queryType, ql);
		if (condition != null && !condition.isEmpty()) {
			q.setProperties(condition);
		}
		Object count = q.uniqueResult();
		return Long.valueOf(String.valueOf(count));
	}

	/**
	 * 获取总记录数
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param values 一个或多个参数值
	 * @return 记录总数
	 */
	protected Long count(QueryType queryType, String ql, Object... values) {
		if (ql == null) {
			return 0L;
		}
		String target = ql.substring(0, ql.toUpperCase().indexOf("FROM"));
		ql = ql.replace(target, "SELECT COUNT(*) ");
		Query q = createQuery(queryType, ql);
		int length = 0;
		if (values != null && (length = values.length) > 0) {
			for (int i = 0; i < length; i++) {
				q.setParameter(i, values[i]);
			}
		}
		Object count = q.uniqueResult();
		return Long.valueOf(String.valueOf(count));
	}

	/**
	 * 执行操作语句
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param list 参数值集合
	 * @return 执行结果
	 */
	protected int execute(QueryType queryType, String ql, List<Object> list) {
		Query q = createQuery(queryType, ql);
		int size = 0;
		if (list != null && (size = list.size()) > 0) {
			for (int i = 0; i < size; i++) {
				q.setParameter(i, list.get(i));
			}
		}
		return q.executeUpdate();
	}

	/**
	 * 执行操作语句
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param condition 查询条件键值对集合
	 * @return 执行结果
	 */
	protected int execute(QueryType queryType, String ql, Map<String, Object> condition) {
		Query q = createQuery(queryType, ql);
		if (condition != null && !condition.isEmpty()) {
			q.setProperties(condition);
		}
		return q.executeUpdate();
	}

	/**
	 * 执行操作语句
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param values 一个或多个参数值
	 * @return 执行结果
	 */
	protected int execute(QueryType queryType, String ql, Object... values) {
		Query q = createQuery(queryType, ql);
		int length = 0;
		if (values != null && (length = values.length) > 0) {
			for (int i = 0; i < length; i++) {
				q.setParameter(i, values[i]);
			}
		}
		return q.executeUpdate();
	}

	/**
	 * 查询返回单个实体对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param list 一个或多个参数值
	 * @return 查询结果
	 */
	@SuppressWarnings("unchecked")
	protected E uniqueQuery(QueryType queryType, String ql, List<Object> list) {
		Query q = createQuery(queryType, ql);
		int size = 0;
		if (list != null && (size = list.size()) > 0) {
			for (int i = 0; i < size; i++) {
				q.setParameter(i, list.get(i));
			}
		}
		return (E) q.uniqueResult();
	}

	/**
	 * 查询返回单个实体对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param condition 查询条件键值对集合
	 * @return 查询结果
	 */
	@SuppressWarnings("unchecked")
	protected E uniqueQuery(QueryType queryType, String ql, Map<String, Object> condition) {
		Query q = createQuery(queryType, ql);
		if (condition != null && !condition.isEmpty()) {
			q.setProperties(condition);
		}
		return (E) q.uniqueResult();
	}

	/**
	 * 查询返回单个实体对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param values 一个或多个参数值
	 * @return 查询结果
	 */
	@SuppressWarnings("unchecked")
	protected E uniqueQuery(QueryType queryType, String ql, Object... values) {
		Query q = createQuery(queryType, ql);
		int length = 0;
		if (values != null && (length = values.length) > 0) {
			for (int i = 0; i < length; i++) {
				q.setParameter(i, values[i]);
			}
		}
		return (E) q.uniqueResult();
	}

	/**
	 * 添加实体
	 * @param e 期望添加的实体对象实例
	 * @return 返回添加后的实体对象实例
	 */
	public E save(E e) {
		Date date = new Date();
		e.setCreateTime(date);
		e.setUpdateTime(date);
		e.setIsDeleted(false);
		getSession().save(e);
		return e;
	}

	/**
	 * 修改实体
	 * @param e 期望修改的实体对象实例
	 * @return 返回修改后的实体对象实例
	 */
	public E update(E e) {
		e.setUpdateTime(new Date());
		e.setIsDeleted(false);
		getSession().update(e);
		return e;
	}

	/**
	 * 物理删除单实体
	 * @param entityClass 实体类型
	 * @param id 期望删除的实体主键
	 * @return 返回删除条数
	 */
	protected int delete(Class<E> entityClass, Integer id) {
		String hql = "DELETE FROM " + entityClass.getName() + " AS _table WHERE _table.id = :id";
		Query q = getSession().createQuery(hql);
		q.setParameter("id", id);
		return q.executeUpdate();
	}

	/**
	 * 物理删除多实体
	 * 
	 * @param entityClass 期望删除的实体类型
	 * @param ids 期望删除的多个实体主键
	 * @return 返回删除条数
	 */
	protected int delete(Class<E> entityClass, Integer[] ids) {
		String hql = "DELETE FROM " + entityClass.getName() + " AS _table WHERE _table.id IN ( :ids )";
		Query q = getSession().createQuery(hql);
		q.setParameterList("ids", ids);
		return q.executeUpdate();
	}

	/**
	 * 物理删除单实体
	 * @param e 期望删除的实体对象实例
	 */
	public void delete(E e) {
		delete(entityClass, e.getId());
		// getSession().delete(e);
	}

	/**
	 * 物理删除单实体
	 * @param id 期望删除的实体主键
	 * @return 返回删除条数
	 */
	public int delete(Integer id) {
		return delete(entityClass, id);
	}

	/**
	 * 物理删除多实体
	 * @param ids 期望删除的多个实体主键
	 * @return 返回删除条数
	 */
	public int delete(Integer[] ids) {
		return delete(entityClass, ids);
	}

	/**
	 * 物理删除多实体
	 * @param es 期望删除的多个实体对象实例
	 */
	public void delete(List<E> es) {
		int size = 0;
		if (es == null || (size = es.size()) <= 0) return;
		Integer[] ids = new Integer[size];
		for (int index = 0; index < size; index++) {
			ids[index] = es.get(index).getId();
		}
		delete(entityClass, ids);
		// for (Iterator<E> iterator = es.iterator(); iterator.hasNext();) {
		// delete(iterator.next());
		// }
	}

	/**
	 * 物理删除所有实体
	 * @return 返回删除的行数
	 */
	public int deleteAll() {
		return deleteAll(entityClass);
	}

	/**
	 * 物理删除所有实体
	 * @param entityClass 实体类型
	 * @return 返回删除的行数
	 */
	protected int deleteAll(Class<E> entityClass) {
		String hql = "DELETE FROM " + entityClass.getName();
		Query query = getSession().createQuery(hql);
		return query.executeUpdate();
	}

	/**
	 * 获取所有实体
	 * @return 返回所有实体对象实例集合
	 */
	public List<E> findAll() {
		return findAll(entityClass);
	}

	/**
	 * 获取所有实体
	 * @param entityClass 实体类型
	 * @return 返回所有指定实体类型的实体对象实例集合
	 */
	protected List<E> findAll(Class<E> entityClass) {
		String hql = "SELECT _table FROM " + entityClass.getName()
				+ " AS _table ORDER BY _table.id ASC";
		Object[] values = null;
		return find(QueryType.HQL, hql, values);
	}

	/**
	 * 分页设置
	 * @param q 查询对象
	 * @param pageNum 页码
	 * @param pageSize 每一页显示记录数
	 * @return 返回查询对象
	 */
	protected Query settingPagination(Query q, int pageNum, int pageSize) {
		if (pageNum > 0 && pageSize > 0) {
			q.setMaxResults(pageSize);
			q.setFirstResult((pageNum - 1) * pageSize);
		}
		return q;
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageNum 页码
	 * @param pageSize 每一页显示记录数
	 * @param list 参数值集合
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	protected List<E> find(QueryType queryType, String ql, int pageNum, int pageSize, List<Object> list) {
		Query q = createQuery(queryType, ql);
		int size = 0;
		if (list != null & (size = list.size()) > 0) {
			for (int i = 0; i < size; i++) {
				q.setParameter(i, list.get(i));
			}
		}

		settingPagination(q, pageNum, pageSize);
		return q.list();
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageNum 页码
	 * @param pageSize 每一页显示记录数
	 * @param condition 查询条件键值对集合
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	protected List<E> find(QueryType queryType, String ql, int pageNum, int pageSize, Map<String, Object> condition) {
		Query q = createQuery(queryType, ql);
		if (condition != null && (!condition.isEmpty())) {
			q.setProperties(condition);
		}

		settingPagination(q, pageNum, pageSize);
		return q.list();
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageNum 页码
	 * @param pageSize 每一页显示记录数
	 * @param values 一个或多个参数值
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	protected List<E> find(QueryType queryType, String ql, int pageNum, int pageSize, Object... values) {
		Query q = createQuery(queryType, ql);
		int length = 0;
		if (values != null && (length = values.length) > 0) {
			for (int i = 0; i < length; i++) {
				q.setParameter(i, values[i]);
			}
		}

		settingPagination(q, pageNum, pageSize);
		return q.list();
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param list 参数值集合
	 * @return 查询结果集
	 */
	protected List<E> find(QueryType queryType, String ql, List<Object> list) {
		return find(queryType, ql, -1, -1, list);
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param condition 查询条件键值对集合
	 * @return 查询结果集
	 */
	protected List<E> find(QueryType queryType, String ql, Map<String, Object> condition) {
		return find(queryType, ql, -1, -1, condition);
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param values 一个或多个参数值
	 * @return 查询结果集
	 */
	protected List<E> find(QueryType queryType, String ql, Object... values) {
		return find(queryType, ql, -1, -1, values);
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageable 分页请求抽象接口
	 * @param list 参数值集合
	 * @return 查询结果集
	 */
	protected Page<E> find(QueryType queryType, String ql, Pageable pageable, List<Object> list) {
		Page<E> page = PageUtill.newPageInstance();
		page.setRecords(find(queryType, ql, pageable.getPage(), pageable.getRows(), list));
		page.setTotal(count(queryType, ql, list));
		return page;
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageable 分页请求抽象接口
	 * @param condition 查询条件键值对集合
	 * @return 查询结果集
	 */
	protected Page<E> find(QueryType queryType, String ql, Pageable pageable, Map<String, Object> condition) {
		Page<E> page = PageUtill.newPageInstance();
		page.setRecords(find(queryType, ql, pageable.getPage(), pageable.getRows(), condition));
		page.setTotal(count(queryType, ql, condition));
		return page;
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageable 分页请求抽象接口
	 * @param values 一个或多个参数值
	 * @return 查询结果集
	 */
	protected Page<E> find(QueryType queryType, String ql, Pageable pageable, Object... values) {
		Page<E> page = PageUtill.newPageInstance();
		page.setPage(pageable.getPage()).setRows(pageable.getRows());
		page.setRecords(find(queryType, ql, pageable.getPage(), pageable.getRows(), values));
		page.setTotal(count(queryType, ql, values));
		return page;
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageNum 页码
	 * @param pageSize 每一页显示记录数
	 * @param values 一个或多个参数值
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	protected List<Map<String, Object>> findForMap(QueryType queryType, String ql, int pageNum, int pageSize, Object... values) {
		Query q = createQuery(queryType, ql);
		int length = 0;
		if (values != null && (length = values.length) > 0) {
			for (int i = 0; i < length; i++) {
				q.setParameter(i, values[i]);
			}
		}

		settingPagination(q, pageNum, pageSize);
		return q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP).list();
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageNum 页码
	 * @param pageSize 每一页显示记录数
	 * @param condition 查询条件键值对集合
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	protected List<Map<String, Object>> findForMap(QueryType queryType, String ql, int pageNum, int pageSize, Map<String, Object> condition) {
		Query q = createQuery(queryType, ql);
		if (condition != null && (!condition.isEmpty())) {
			q.setProperties(condition);
		}

		settingPagination(q, pageNum, pageSize);
		return q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP).list();
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageable 分页请求抽象接口
	 * @param condition 查询条件键值对集合
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	protected List<Map<String, Object>> findForMap(QueryType queryType, String ql, Map<String, Object> condition) {
		Query q = createQuery(queryType, ql);
		if (condition != null && (!condition.isEmpty())) {
			q.setProperties(condition);
		}

		return q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP).list();
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param values 一个或多个参数值
	 * @return 查询结果集
	 */
	protected List<Map<String, Object>> findForMap(QueryType queryType, String ql, Object... values) {
		return findForMap(queryType, ql, -1, -1, values);
	}
	
	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageable 分页请求抽象接口
	 * @param condition 查询条件键值对集合
	 * @return 查询结果集
	 */
	protected Page<Map<String, Object>> findForMap(QueryType queryType, String ql, Pageable pageable, Map<String, Object> condition) {
		Page<Map<String, Object>> page = PageUtill.newPageInstance();
		page.setRecords(findForMap(queryType, ql, pageable.getPage(), pageable.getRows(), condition));
		page.setTotal(count(queryType, ql, condition));
		return page;
	}

	/**
	 * 查询对象
	 * @param queryType 查询类型.HQL/SQL;参见枚举:{@link tangjl.financial.dao.AbstractBaseDao.QueryType}
	 * @param ql HQL/SQL语句.必须使用queryType指定的类型
	 * @param pageable 分页请求抽象接口
	 * @param values 一个或多个参数值
	 * @return 查询结果集
	 */
	protected Page<Map<String, Object>> findForMap(QueryType queryType, String ql, Pageable pageable, Object... values) {
		Page<Map<String, Object>> page = PageUtill.newPageInstance();
		page.setRecords(findForMap(queryType, ql, pageable.getPage(), pageable.getRows(), values));
		page.setTotal(count(queryType, ql, values));
		return page;
	}

	/**
	 * 获取指定实体类型的实体对象实例
	 * @param entityClass 实体类型
	 * @param id 实体主键
	 * @return 返回获取的实体对象实例
	 */
	@SuppressWarnings("unchecked")
	protected E get(Class<E> entityClass, Integer id) {
		if (id == null) { return null; }
		return (E) getSession().get(entityClass, id);
	}

	/**
	 * 获取实体对象实例
	 * @param id 实体主键
	 * @return 返回获取的实体对象实例
	 */
	public E get(Integer id) {
		return get(entityClass, id);
	}

	/**
	 * 逻辑删除单实体
	 * @param entityClass 实体类型
	 * @param id 期望删除的实体主键
	 */
	protected void logicDelete(Class<E> entityClass, Integer id) {
		logicDelete(get(entityClass, id));
	}

	/**
	 * 逻辑删除多实体
	 * @param entityClass 实体类型
	 * @param ids 期望删除的多个实体主键
	 */
	protected void logicDelete(Class<E> entityClass, Integer[] ids) {
		for (Integer id : ids) {
			logicDelete(entityClass, id);
		}
	}

	/**
	 * 逻辑删除单实体
	 * @param e 期望删除的实体对象实例
	 */
	public void logicDelete(E e) {
		e.setDeleteTime(new Date());
		e.setIsDeleted(true);
		getSession().update(e);
	}

	/**
	 * 逻辑删除单实体
	 * @param id 期望删除的实体主键
	 */
	public void logicDelete(Integer id) {
		logicDelete(entityClass, id);
	}

	/**
	 * 逻辑删除多实体
	 * @param ids 期望删除的多个实体主键
	 */
	public void logicDelete(Integer[] ids) {
		logicDelete(entityClass, ids);
	}

	/**
	 * 逻辑删除多实体
	 * @param es 希望删除的多个实体对象实例
	 */
	public void logicDelete(List<E> es) {
		if (null == es || es.size() <= 0) return;
		for (Iterator<E> iterator = es.iterator(); iterator.hasNext();) {
			logicDelete(iterator.next());
		}
	}

	/**
	 * 恢复逻辑删除的单实体
	 * @param entityClass 实体类型
	 * @param id 期望删除的实体主键
	 */
	protected void disLogicDelete(Class<E> entityClass, Integer id) {
		disLogicDelete(get(entityClass, id));
	}

	/**
	 * 恢复逻辑删除的多实体
	 * @param entityClass 实体类型
	 * @param ids 期望删除的多个实体主键
	 */
	protected void disLogicDelete(Class<E> entityClass, Integer[] ids) {
		for (Integer id : ids) {
			disLogicDelete(entityClass, id);
		}
	}

	/**
	 * 恢复逻辑删除的单实体
	 * @param e 期望删除的实体对象实例
	 */
	public void disLogicDelete(E e) {
		e.setDeleteTime(new Date());
		e.setIsDeleted(false);
		getSession().update(e);
	}

	/**
	 * 恢复逻辑删除的单实体
	 * @param id 期望删除的实体主键
	 */
	public void disLogicDelete(Integer id) {
		disLogicDelete(entityClass, id);
	}

	/**
	 * 恢复逻辑删除的多实体
	 * @param ids 期望删除的多个实体主键
	 */
	public void disLogicDelete(Integer[] ids) {
		disLogicDelete(entityClass, ids);
	}

	/**
	 * 恢复逻辑删除的多实体
	 * @param es 希望删除的多个实体对象实例
	 */
	public void disLogicDelete(List<E> es) {
		if (null == es || es.size() <= 0) return;
		for (Iterator<E> iterator = es.iterator(); iterator.hasNext();) {
			disLogicDelete(iterator.next());
		}
	}

	/**
	 * 创建查询对象
	 * @param querytype 查询类型
	 * @param ql 查询语句
	 * @return 返回查询对象
	 */
	protected Query createQuery(QueryType querytype, String ql) {
		if (querytype == null) throw new IllegalArgumentException("未指定查询类型");
		Session session = getSession();
		Query q = null;
		switch (querytype) {
		case HQL:
			q = session.createQuery(ql);
			break;
		case SQL:
			q = session.createSQLQuery(ql);
			break;
		default:
			q = session.createQuery(ql);
			break;
		}
		return q;
	}

	/**
	 * 创建Criteria对象
	 * @return 返回Criteria
	 */
	protected Criteria createCriteria() {
		return createCriteria(entityClass);
	}

	/**
	 * 创建Criteria对象
	 * @param entityClass 实体类型
	 * @return 返回Criteria
	 */
	protected Criteria createCriteria(Class<E> entityClass) {
		return getSession().createCriteria(entityClass);
	}

	/**
	 * 查询类型枚举
	 * @author 唐家林
	 * @time 2015年6月22日
	 */
	public enum QueryType {
		HQL,SQL
	}
}